﻿using System.ComponentModel;
using System.Configuration.Install;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System;
using System.Xml.Linq;
using System.Xml;
using System.Reflection;
using System.Linq;
using System.Windows.Forms;


namespace ClassMetadataBrowser.Install
{
	[RunInstaller(true)]
	public partial class AddinInstaller : Installer
	{
		private const string AddinAssembly = "ClassMetadataBrowser.dll";
		private const string AddinFileName = "ClassMetadataBrowser.AddIn";
		private const string AddinFileStateKey = "AddinFile";

		public AddinInstaller()
		{
			InitializeComponent();

			this.AfterUninstall += new InstallEventHandler(AddinInstaller_AfterUninstall);
		}

		public void AddinInstaller_AfterUninstall(object sender, InstallEventArgs e)
		{
			UninstallAddinFile(e.SavedState);
		}

		public override void Install(IDictionary stateSaver)
		{
#if DEBUG
			Debugger.Break();
#endif
			try
			{
				string addinAssemblyLocation = Path.GetDirectoryName(this.Context.Parameters["AssemblyPath"]);
				string sourceFile = Path.Combine(addinAssemblyLocation, AddinFileName);
				string addinFilePath = CreateAddinFilePath();
				DeleteAddinFile(addinFilePath);

				XDocument document = XDocument.Load(sourceFile);

				const string addinTag = "Addin";
				const string assemblyTag = "Assembly";

				XElement addin = document.Root.Elements().Where(e => e.Name.LocalName == addinTag).SingleOrDefault();
				if (addin == null)
					return;
				XElement assembly = addin.Elements().Where(e => e.Name.LocalName == assemblyTag).SingleOrDefault();
				if (assembly == null)
					return;

				assembly.Value = Path.Combine(addinAssemblyLocation, AddinAssembly);
				document.Save(sourceFile);

				File.Copy(sourceFile, addinFilePath);
				stateSaver.Add(AddinFileStateKey, addinFilePath);
				base.Install(stateSaver);
			}
			catch(Exception ex)
			{
				throw new ApplicationException(string.Format("Error occured while installation. More Info: '{0}'", ex.Message));
			}
		}

		public string CreateAddinFilePath()
		{
			string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

			string microsftPath = Path.Combine(folderPath, "Microsoft");
			if (!Directory.Exists(microsftPath))
				Directory.CreateDirectory(microsftPath);

			string msenvShared = Path.Combine(microsftPath, "MSEnvShared");
			if (!Directory.Exists(msenvShared))
				Directory.CreateDirectory(msenvShared);

			string addinFolder = Path.Combine(msenvShared, "Addins");
			if (!Directory.Exists(addinFolder))
				Directory.CreateDirectory(addinFolder);

			return Path.Combine(folderPath, @"Microsoft\MSEnvShared\Addins\" + AddinFileName);
		}

		private void UninstallAddinFile(IDictionary savedState)
		{
			if (savedState != null && savedState.Contains(AddinFileStateKey))
			{
				DeleteAddinFile((string)savedState[AddinFileStateKey]);
				savedState.Remove(AddinFileStateKey);
			}
		}

		private void DeleteAddinFile(string addinFile)
		{
			if (File.Exists(addinFile))
			{
				FileInfo file = new FileInfo(addinFile);
				file.Delete();
			}
		}
	}
}
